
package com.avrio.json;

// <editor-fold defaultstate="collapsed" desc="import">
import java.io.IOException;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
// </editor-fold>

@SuppressWarnings("serial")
public abstract class JsonValue implements Serializable {

    public static final JsonValue TRUE  = new JsonLiteral("true");
    public static final JsonValue FALSE = new JsonLiteral("false");
    public static final JsonValue NULL  = new JsonLiteral("null");

// <editor-fold defaultstate="collapsed" desc="JsonValue()">

    public JsonValue() {
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="readFrom()">

    public static JsonValue readFrom(Reader reader) throws IOException {
        return new JsonParser(reader).parse();
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="readFrom()">

    public static JsonValue readFrom(String text) {

        try {
            return new JsonParser(text).parse();
        }
        catch(IOException exception) {
            throw new RuntimeException(exception);
        }
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="valueOf(int)">

    public static JsonValue valueOf(int value) {
        return new JsonNumber(Integer.toString(value, 10));
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="valueOf(long)">

    public static JsonValue valueOf(long value) {
        return new JsonNumber(Long.toString(value, 10));
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="valueOf(float)">

    public static JsonValue valueOf(float value) {

        if(Float.isInfinite(value) || Float.isNaN(value)) {
            throw new IllegalArgumentException("Infinite and NaN values not permitted in JSON");
        }
        return new JsonNumber(cutOffPointZero(Float.toString(value)));
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="valueOf(double)">

    public static JsonValue valueOf(double value) {
        if (Double.isInfinite(value) || Double.isNaN(value)) {
            throw new IllegalArgumentException("Infinite and NaN values not permitted in JSON");
        }
        return new JsonNumber(cutOffPointZero(Double.toString(value)));
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="valueOf(String)">

    public static JsonValue valueOf(String string) {
        return string == null ? NULL : new JsonString(string);
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="valueOf(boolean)">

    public static JsonValue valueOf(boolean value) {
        return value ? TRUE : FALSE;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isObject()">

    public boolean isObject() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isArray()">

    public boolean isArray() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isNumber()">

    public boolean isNumber() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isString()">

    public boolean isString() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isBoolean()">

    public boolean isBoolean() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isTrue()">

    public boolean isTrue() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isFalse()">

    public boolean isFalse() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="isNull()">

    public boolean isNull() {
        return false;
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asObject()">

    public JsonObject asObject() {
        throw new UnsupportedOperationException("Not an object: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asArray()">

    public JsonArray asArray() {
        throw new UnsupportedOperationException("Not an array: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asInt()">

    public int asInt() {
        throw new UnsupportedOperationException("Not a number: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asLong()">

    public long asLong() {
        throw new UnsupportedOperationException("Not a number: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asFloat()">

    public float asFloat() {
        throw new UnsupportedOperationException("Not a number: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asDouble()">

    public double asDouble() {
        throw new UnsupportedOperationException("Not a number: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asString()">

    public String asString() {
        throw new UnsupportedOperationException("Not a string: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="asBoolean()">

    public boolean asBoolean() {
        throw new UnsupportedOperationException("Not a boolean: " + toString());
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="writeTo()">

    public void writeTo(Writer writer) throws IOException {
        write(new JsonWriter(writer));
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="toString()">

    @Override
    public String toString() {
        StringWriter stringWriter = new StringWriter();
        JsonWriter jsonWriter = new JsonWriter(stringWriter);
        try {
            write(jsonWriter);
        }
        catch (IOException exception) {
            throw new RuntimeException(exception);
        }
        return stringWriter.toString();
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="equals()">

    @Override
    public boolean equals(Object object) {
        return super.equals(object);
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="hashCode()">

    @Override
    public int hashCode() {
        return super.hashCode();
    }
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="write()">

    protected abstract void write(JsonWriter writer) throws IOException;
// </editor-fold>

// <editor-fold defaultstate="collapsed" desc="cutOffPointZero()">

    private static String cutOffPointZero(String string) {

        if(string.endsWith(".0")) {
            return string.substring(0, string.length() - 2);
        }

        return string;
    }
// </editor-fold>
}
